/*** 
 * @_______________#########_______________________ 
 * @______________############_____________________ 
 * @______________#############____________________ 
 * @_____________##__###########___________________ 
 * @____________###__######_#####__________________ 
 * @____________###_#######___####_________________ 
 * @___________###__##########_####________________ 
 * @__________####__###########_####_______________ 
 * @________#####___###########__#####_____________ 
 * @_______######___###_########___#####___________ 
 * @_______#####___###___########___######_________ 
 * @______######___###__###########___######_______ 
 * @_____######___####_##############__######______ 
 * @____#######__#####################_#######_____ 
 * @____#######__##############################____ 
 * @___#######__######_#################_#######___ 
 * @___#######__######_######_#########___######___ 
 * @___#######____##__######___######_____######___ 
 * @___#######________######____#####_____#####____ 
 * @____######________#####_____#####_____####_____ 
 * @_____#####________####______#####_____###______ 
 * @______#####______;###________###______#________ 
 * @________##_______####________####______________ 
 * @
 * @Author: ipk518 18163976442@163.com
 * @Date: 2024-11-23 10:56:38
 * @LastEditors: ipk518 121206530@qq.com
 * @LastEditTime: 2025-09-03 15:39:49
 * @FilePath: /etws-sxk2307/src/Uio/autoCalibration.cpp
 * @Description: 
 * @************佛祖保佑************
 * @Copyright (c) 2024 by etws@quyujiang, All Rights Reserved. 
 */


#include "Server.h"
#include "math.h"
#include <ctime>
#include "getConfig.h"
#include "autoCalibration.h"
#include "Gpio.h"
#include "queueShare.h"
#include "Uio.h"

using namespace std;

#define FREQPOINT_0 0
#define FREQPOINT_1 1


#define CHANNEL_NUM 32

#define AUTO_CALCULATE_AMP          0
#define AUTO_CALCULATE_PHASE        1
#define AUTO_CALCULATE_AMP_PHASE    2
#define AUTO_CALCULATE_RECV         3


#define AUTO_CALCULATE          0
#define MANUAL_CALCULATE        1

static uint16_t m_srcAp[64]; //校准原始值，用于打印等
//发射基准值;需要*100;*10;
struct tr_mulit_freq_t mulitFreqStr;

//发射
struct ap_Control_t ddsCacheStr_H;
struct ap_Control_t ddsCacheStr_V;
struct ap_Control_t ddsSendStr;

//接收基准值;需要*100;*10;
struct recv_mulit_freq_t recvMulitFreqStr;

struct ap_Control_t ddsCacheRecv_H;
struct ap_Control_t ddsCacheRecv_V;
struct ap_Control_t ddsRecvStr;

std::atomic<bool> m_refreshSendH(false);//水平数据刷新标志位
std::atomic<bool> m_refreshSendV(false);//水平数据刷新标志位
std::atomic<bool> m_refreshRecvH(false);//水平数据刷新标志位
std::atomic<bool> m_refreshRecvV(false);//水平数据刷新标志位

crontab_uio::crontab_uio( )
{
    memset((uint8_t *)&ddsCacheStr_H,0,sizeof(ddsCacheStr_H));
    memset((uint8_t *)&ddsCacheStr_V,0,sizeof(ddsCacheStr_V));
    memset((uint8_t *)&ddsSendStr,0,sizeof(ddsSendStr));

    memset((uint8_t *)&ddsCacheRecv_H,0,sizeof(ddsCacheRecv_H));
    memset((uint8_t *)&ddsCacheRecv_V,0,sizeof(ddsCacheRecv_V));
    memset((uint8_t *)&ddsRecvStr,0,sizeof(ddsRecvStr));

    memset((uint8_t *)&mulitFreqStr.hRecAmp[0],0,sizeof(mulitFreqStr));
    memset(&recvMulitFreqStr,0,sizeof(recvMulitFreqStr));

    m_refreshSendH = false;
    m_refreshSendV = false;
    m_refreshRecvH = false;
    m_refreshRecvV = false;
    init();
}

crontab_uio::~crontab_uio()
{
    taskProcess = t_init;
    taskProcess1 = t_init;
    m_RunFlag = false;
    if (CrontabFd != nullptr) {
        CrontabFd->join();
        delete CrontabFd;
    }
    
    if (m_hSendCaliQueue != nullptr) {
        m_hSendCaliQueue->removeAll();
        delete m_hSendCaliQueue;
    }

    if (m_vSendCaliQueue != nullptr) {
        m_vSendCaliQueue->removeAll();
        delete m_vSendCaliQueue;
    }

    if (m_vRevCaliQueue != nullptr) {
        m_vRevCaliQueue->removeAll();
        delete m_vRevCaliQueue;
    }
    
    if (m_hRevCaliQueue != nullptr) {
        m_hRevCaliQueue->removeAll();
        delete m_hRevCaliQueue;
    }
}



void crontab_uio::init()
{
    m_hSendCaliQueue = new queueShare();
    if (m_hSendCaliQueue == nullptr)
    {
       qlog_e("自动校准发射H极化数据队列初始化失败!");
        return;
    }  
    m_vSendCaliQueue = new queueShare();
    if (m_vSendCaliQueue == nullptr)
    {
        qlog_e("自动校准发射V极化数据队列初始化失败!");
        return;
    }  
    m_hRevCaliQueue = new queueShare();
    if (m_hRevCaliQueue == nullptr)
    {
        qlog_e("自动校准接收H极化数据队列初始化失败!");
        return;
    }  
    m_vRevCaliQueue = new queueShare();
    if (m_vRevCaliQueue == nullptr)
    {
        qlog_e("自动校准接收V极化数据队列初始化失败!");
        return;
    }  
    taskProcess = t_init;
    taskProcess1 = t_init;
    m_RunFlag = true;

    string str = Conf::currentConf()->mFilePath.uFreqReferencePath + string("/") + _REFERENCE_VALUE_ ;
    if(ReadFile(str.c_str(),(unsigned char *)&mulitFreqStr.hRecAmp[0],sizeof(mulitFreqStr)) < 0){
        qlog_e("没有发现文件 %s.",str.c_str());
        qlog_w("发射自动校准的基准值使用内部默认值");
    }

    str = Conf::currentConf()->mFilePath.uFreqReferencePath + string("/") + _RECV_REFERENCE_VALUE_ ;
    if(ReadFile(str.c_str(),(unsigned char *)&recvMulitFreqStr.hRecvAmp[0],sizeof(recvMulitFreqStr)) < 0){
        qlog_e("没有发现文件 %s.",str.c_str());
        qlog_w("接收自动校准的基准值使用内部默认值.130,0");
        for(int i=0;i<CHANNEL_NUM;i++)//内部初始化
        {
            recvMulitFreqStr.hRecvAmp[0][i] = 13000;
            recvMulitFreqStr.hRecvAmp[1][i] = 13000;
            recvMulitFreqStr.hRecvPhase[0][i] = 0;
            recvMulitFreqStr.hRecvPhase[1][i] = 0;

            recvMulitFreqStr.vRecvAmp[0][i] = 13000;
            recvMulitFreqStr.vRecvAmp[1][i] = 13000;
            recvMulitFreqStr.vRecvPhase[0][i] = 0;
            recvMulitFreqStr.vRecvPhase[1][i] = 0;
        }
    }
    readCouplingParameters();//获取耦合系数
    CrontabFd = new std::thread(std::bind(&crontab_uio::crontab_Thread_Func, this));//定时任务
}

/*** 
 * @description: 设置雷象上报命令
 * @param {uioMode} m
 * @param {cmdDataType} *cmd
 * @return {*}
 */
static void setWebCmd(uioMode m,cmdDataType *cmd)
{
    switch(m)
    {
        case uio_h_sendPolar:
            cmd->cmdType = 2;
            cmd->cmdChildType = 2;
        break;
        case uio_v_sendPolar:
            cmd->cmdType = 2;
            cmd->cmdChildType = 3;
        break;
        case uio_h_recvicePolar:
            cmd->cmdType = 2;
            cmd->cmdChildType = 0;
        break;
        case uio_v_recvicePolar:
            cmd->cmdType = 2;
            cmd->cmdChildType = 1;
        break;
        default:
        break;
    }
}

void crontab_uio::test(char* m,int len)
{
    if(len < 2) {
        qlog_e("crontab_uio,test参数错误");
        return;
    }
    int m_tesk = m[0];//模式
    taskFreq = Server::Instance().m_gloabl.SpecifiedFreq;
    if(taskFreq > 1) {
        qlog_e("crontab_uio,频点信息错误=%d.",taskFreq);
        return;
    }
    //循环次数
    g_manualAmpCnt = m[1];
    g_manualPhaCnt = g_manualAmpCnt;
    taskProcess = (taskprocess)m_tesk;
    taskProcess1 = (taskprocess)m_tesk;

    
    

}

/*** 
 * @description: 需要去掉2个字节的频点信息
 * @param {int} m_flag
 * @return {*}
 */
void crontab_uio::update(int m_flag,vector<uint8_t>& dataIn)
{
    if (taskProcess == t_getGps && taskProcess1 == t_wait) {
        return;
    }
    
    if (m_flag == uio_h_sendPolar) {
        std::unique_lock <std::mutex> lock(g_CaliMutex); 
        if ( m_hSendCaliQueue->dataIsValid() ) {
            m_hSendCaliQueue->removeAll();
        }
        m_hSendCaliQueue->recvfrom(dataIn.data(),dataIn.size());
        m_refreshSendH = true;
    }
    if (m_flag == uio_v_sendPolar) {
        std::unique_lock <std::mutex> lock(g_CaliMutex); 
        if ( m_vSendCaliQueue->dataIsValid() ) {
            m_vSendCaliQueue->removeAll();
        }
        m_vSendCaliQueue->recvfrom(dataIn.data(),dataIn.size());
        m_refreshSendV = true;
    }
    if (m_flag == uio_h_recvicePolar) {
        std::unique_lock <std::mutex> lock(g_CaliMutex); 
        if ( m_hRevCaliQueue->dataIsValid() ) {
            m_hRevCaliQueue->removeAll();
        }
        m_hRevCaliQueue->recvfrom(dataIn.data(),dataIn.size());
        m_refreshRecvH = true;
    }
    if (m_flag == uio_v_recvicePolar) {
        std::unique_lock <std::mutex> lock(g_CaliMutex); 
        if ( m_vRevCaliQueue->dataIsValid() ) {
            m_vRevCaliQueue->removeAll();
        }
        m_vRevCaliQueue->recvfrom(dataIn.data(),dataIn.size());
        m_refreshRecvV = true;
    }
}

bool crontab_uio::wait(uioMode m)
{
    bool ret = false;
    int timeout = 0;
    if (m == uio_h_sendPolar) {
        while ( !m_refreshSendH.load() ) {
            timeout++;
            if(timeout > 40) {
                timeout = 0;
                qlog_e("等待H极化发射校准数据刷新超时.");
                return ret;
            }
            qlog_w("等待H极化发射校准数据刷新.");
            std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 控制等待频率
        }
    }
    if (m == uio_v_sendPolar) {
        while ( !m_refreshSendV.load() ) {
            timeout++;
            if(timeout > 40) {
                timeout = 0;
                qlog_e("等待V极化发射校准数据刷新超时.");
                return ret;
            }
            qlog_w("等待V极化发射校准数据刷新.");
            std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 控制等待频率
        }
    }
    if (m == uio_h_recvicePolar) {
        while ( !m_refreshRecvH.load() ) {
            timeout++;
            if(timeout > 40) {
                timeout = 0;
                qlog_e("等待H极化接收校准数据刷新超时.");
                return ret;
            }
            qlog_w("等待H极化接收校准数据刷新.");
            std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 控制等待频率
        }
    }
    if (m == uio_v_recvicePolar) {
        while ( !m_refreshRecvV.load() ) {
            timeout++;
            if(timeout > 40) {
                timeout = 0;
                qlog_e("等待V极化接收校准数据刷新超时.");
                return ret;
            }
            qlog_w("等待V极化接收校准数据刷新.");
            std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 控制等待频率
        }
    }
    ret = true;
    return ret;
}

/*** 
 * @description: 用于下发TR组件控制
 * @param {uioMode} to
 * @param {unsigned char} *dataOut
 * @param {unsigned int} dataLen
 * @return {*}
 */
int crontab_uio::send(uioMode to,unsigned char *dataOut,unsigned int dataLen)
{
    int cmdTo = 0;
    int sendnum=0x01;
    static struct cmdDataType cmdHeader;
    if (to == uio_h_recvicePolar || to == uio_v_recvicePolar) {//接收校准
        cmdTo = (to == uio_h_recvicePolar)?11:12;
    }
    else if (to == uio_h_sendPolar || to == uio_v_sendPolar) {//发射校准
        cmdTo = (to == uio_h_sendPolar)?9:10;

        cmdHeader.DeviceType = t_controlCmd;
        cmdHeader.source_DevType = CurDeviceType;
        cmdHeader.source_DevNum = ComponentNO;
        cmdHeader.dst_DevType =  T_R_Sub_Unit_S;
        cmdHeader.dst_DevNum = 0;
        cmdHeader.cmdType = d_trCmd;
        cmdHeader.cmdChildType = cmdTo;
        cmdHeader.dataLen = dataLen;

        sendnum=0x01;
        Server::Instance().separate(s_dds,sendnum,&cmdHeader,dataOut);
        sendnum=0x02;
        cmdHeader.dst_DevNum = 1;
        std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 控制等待频率
        Server::Instance().separate(s_dds,sendnum,&cmdHeader,dataOut);
    }

    return 0;
}


/*** 
 * @description: 用于雷象差值上报
 * @param {uioMode} to
 * @return {*}
 */
void crontab_uio::send(uioMode to)
{
    int sendnum=0xFFFF;
    struct cmdDataType cmdHeader;
    cmdHeader.DeviceType = t_controlCmd;
    cmdHeader.source_DevType = CurDeviceType;
    cmdHeader.source_DevNum = ComponentNO;
    cmdHeader.dst_DevType =  leixing_SERVER_Sub_Unit_S;
    cmdHeader.dst_DevNum = 0;

    if (to == uio_h_sendPolar) {//发射校准
        cmdHeader.cmdType = 0x0b;
        cmdHeader.cmdChildType = 1;
    } 
    if (to == uio_v_sendPolar) {
        cmdHeader.cmdType = 0x0b;
        cmdHeader.cmdChildType = 2;
    }
    if (to == uio_h_recvicePolar) {//接收校准
        cmdHeader.cmdType = 0x0b;
        cmdHeader.cmdChildType = 3;
    }
    if (to == uio_v_recvicePolar) {
        cmdHeader.cmdType = 0x0b;
        cmdHeader.cmdChildType = 4;
    }
    cmdHeader.dataLen = sizeof(struct ap_update_t);
    Server::Instance().separate(s_web,sendnum,&cmdHeader,(uint8_t *)&webCache);
    // qlog_hexdump("自动校准Cmd",16,(uint8_t *)&cmdHeader,sizeof(cmdHeader));
    // qlog_hexdump("自动校准Data",16,dataOut,dataLen);
}

bool crontab_uio::getGps(unsigned long dueTime)
{
    if (Server::Instance().m_sxk.m_sysConfig.AutoCalibrationEN == 1) {
        time_t curTime;
        time(&curTime);//"1970到目前经过秒数:"机器内部计数

        int64_t handleTime = curTime - Server::Instance().m_sxk.m_sysConfig.AutoClockMark;
        if (handleTime >= (int64_t)dueTime) {
            taskFreq = Server::Instance().m_gloabl.SpecifiedFreq;//配置校准频率
            qlog_i("触发间隔时间:%ds,时间间隔掩码:%d,当前时间:%d.",handleTime
            ,Server::Instance().m_sxk.m_sysConfig.AutoClockMark,curTime);
            qlog_i("触发自动校准,校准频点:%d",taskFreq);
            Server::Instance().m_sxk.m_sysConfig.AutoClockMark = curTime;//重置时间
            return true;//调试应该为TRUE
        } else {
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            return false;
        }
    }
    return false;
}


/*** 
 * @description: 自动校准
 * 1.PS通过GPS获取时间信息
 * 2.PS判断是否到校准时间节点
 * 3.AXI GPIO外设写1，然后写0
 * setGpioValue(PL_AUTO_ALIGN,1);
 * for(i=0;i<65536;i++){};
 * setGpioValue(PL_AUTO_ALIGN,0);
 * 4.等待时序发生器向PS发送校准完成中断
 * 5.获取发射通道校准IQ数据，并开始计算每个通道的幅度相位信息
 * 6.计算完成后将两个极化通道信息同上位机下发的通道幅相信息进行比较，并计算每个通道的幅相偏移值
 * 7.PS根据偏移值计算出修正值随后下发到TR对发射通道进行修正
 * 
 * @return {*}
 */
void crontab_uio::autoPoll()
{
    static bool m_flag=true;
    static uioMode m_status;
    switch(taskProcess)
    {
        case t_wait:
        break;
        case t_getGps:
            m_flag = getGps(Server::Instance().m_sxk.m_sysConfig.AutoCalibrationTime);
            (m_flag == true)?taskProcess = t_dueNode:taskProcess = t_getGps;
        break;
        case t_dueNode:
            m_flag = startOperate();
            if (m_flag == true) 
            {
                taskProcess = t_timingHandle;
                qlog_i("准备开始雷达自动校准,正在关闭发射赋性使能...");
            } else {
                taskProcess = t_getGps;
                qlog_i("雷达未运行，自动校准无法执行!");
            }
        break;
        case t_timingHandle:
            {
                taskProcess = t_hSendValHandle;
                setGpioValue(Conf::currentConf()->mGpioConf.uPlAutoAlign,1);
                for(int i=0;i<65536;i++){};
                setGpioValue(Conf::currentConf()->mGpioConf.uPlAutoAlign,0);
                qlog_w("触发雷达自动校准...");
            }
        break;
        case t_hSendValHandle:
            qlog_w("自动校准运行中，请勿操作,H发射校准数据处理...");
            m_status = calcOffsetValue2(uio_h_sendPolar,taskFreq,true,AUTO_CALCULATE_AMP_PHASE);
            if (m_status == uio_h_sendPolar) {
                taskProcess = t_vSendValHandle;
            } else {
                taskProcess = t_end;
            }
        break;
        case t_vSendValHandle:
            qlog_w("自动校准运行中，请勿操作,V发射校准数据处理...");
            m_status = calcOffsetValue2(uio_v_sendPolar,taskFreq,true,AUTO_CALCULATE_AMP_PHASE);
            if (m_status == uio_v_sendPolar) {
                taskProcess = t_hRecvValHandle;
            } else {
                taskProcess = t_end;
            }
            
        break;
        case t_hRecvValHandle:
            qlog_w("自动校准运行中，请勿操作,H接收校准数据处理...");
            m_status = calcOffsetValue2(uio_h_recvicePolar,taskFreq,true,AUTO_CALCULATE_RECV);
            if (m_status == uio_h_recvicePolar) {
                recvCompensation(uio_h_recvicePolar,taskFreq,AUTO_CALCULATE,ddsCacheRecv_H);
                taskProcess = t_vRecvValHandle;
            } else {
                taskProcess = t_end;
            }
        break;
        case t_vRecvValHandle:
            qlog_w("自动校准运行中，请勿操作,V接收校准数据处理...");
            m_status = calcOffsetValue2(uio_v_recvicePolar,taskFreq,true,AUTO_CALCULATE_RECV);
            if (m_status == uio_v_recvicePolar) {
                recvCompensation(uio_v_recvicePolar,taskFreq,AUTO_CALCULATE,ddsCacheRecv_V);
            }
            taskProcess = t_end;
        break;
        case t_end:
            {
                taskProcess = t_getGps;
                qlog_w("雷达自动校准,已完成!");
            }
        break;
        default:
            {
                taskProcess = t_getGps;
                qlog_n("雷达自动校准,复位!");
            }
        break;
    }

}

/*  0：更新通道系数 
    1：不减耦合系数、不减通道系数；
    2：减通道系数；
    3：减耦合系数；
    4：减耦合系数、减通道系数；*/
void crontab_uio::task()
{
    switch (taskProcess1) {
        case t_wait:
        break;
        case t_hCyclicTask:
            {
                string msg = "执行H极化发射校准,更新H极化系数";
                qlog_w("%s.",msg.c_str());

                if (g_manualAmpCnt > 0) {
                    g_manualAmpCnt--;
                    startCali(uio_h_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_h_sendPolar,taskFreq,false,AUTO_CALCULATE_AMP);
                    string msg1 = "可运行H极化发射校准手动幅度补偿的计数: " + to_string(g_manualAmpCnt);
                    qlog_w("%s.",msg1.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }
                else if ( g_manualAmpCnt == 0 && g_manualPhaCnt != 0 ) {
                    g_manualPhaCnt--;
                    startCali(uio_h_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_h_sendPolar,taskFreq,false,AUTO_CALCULATE_PHASE);
                    string msg1 = "可运行H极化发射校准手动相位补偿的计数: " + to_string(g_manualPhaCnt);
                    qlog_w("%s.",msg1.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }

                if (g_manualAmpCnt == 0 && g_manualPhaCnt == 0) {
                    taskProcess1 = t_end;//结束
                }


            }
        break;
        case t_vCyclicTask:
            {
                string msg = "执行V极化发射校准,更新H极化系数";
                qlog_w("%s.",msg.c_str());

                if (g_manualAmpCnt > 0) {
                    g_manualAmpCnt--;
                    startCali(uio_v_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_v_sendPolar,taskFreq,false,AUTO_CALCULATE_AMP);
                    msg = "可运行V极化发射校准手动幅度补偿的计数: " + to_string(g_manualAmpCnt);
                    qlog_w("%s.",msg.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }
                else if ( g_manualAmpCnt == 0 && g_manualPhaCnt != 0 ) {
                    g_manualPhaCnt--;
                    startCali(uio_v_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_v_sendPolar,taskFreq,false,AUTO_CALCULATE_PHASE);
                    msg = "可运行V极化发射校准手动相位补偿的计数: " + to_string(g_manualPhaCnt);
                    qlog_w("%s.",msg.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }

                if(g_manualAmpCnt == 0 && g_manualPhaCnt == 0) {
                    taskProcess1 = t_end;////结束
                }

            }
        break;
        case t_hSendCali:
            {
                string msg = "执行H极化发射校准,清幅相,不减耦合系数、不减通道系数";
                qlog_w("%s.",msg.c_str());
                sendCalibration(uio_h_sendPolar,true); 
                taskProcess1 = t_end;
            }
        break;
        case t_vSendCali:
            {
                string msg = "执行V极化发射校准,清幅相,不减耦合系数、不减通道系数";
                qlog_w("%s.",msg.c_str());
                sendCalibration(uio_v_sendPolar,true);
                taskProcess1 = t_end;
            }
        case t_hSubtractCoffeTask: 
            {
                string msg = "执行H发射减通道系数";
                qlog_w("%s.",msg.c_str());
                sendCalibration(uio_h_sendPolar,false);
                taskProcess1 = t_end;
                
            }
        break;
        case t_vSubtractCoffeTask: 
            {
                string msg = "执行V发射减通道系数";
                qlog_w("%s.",msg.c_str());
                sendCalibration(uio_v_sendPolar,false);
                taskProcess1 = t_end;
                
            }
        break;
        

        break;
        case t_hSubCoffeTask:
            {
                string msg = "执行H极化发射校准,减耦合系数";
                qlog_w("%s.",msg.c_str());
                startCali(uio_h_sendPolar);
                subCouplingCoffe(uio_h_sendPolar);
                taskProcess1 = t_end;
            }

        break;
        case t_vSubCoffeTask:
            {
                string msg = "执行V极化发射校准,减耦合系数";
                qlog_w("%s.",msg.c_str());
                startCali(uio_v_sendPolar);
                subCouplingCoffe(uio_v_sendPolar);
                taskProcess1 = t_end;
            }

        break;
        case t_hCSubCoffeTask:
            {
                string msg = "执行H极化发射校准,减耦合系数、减通道系数";
                qlog_w("%s.",msg.c_str());
                startCali(uio_h_sendPolar);
                sendCalibSubC(uio_h_sendPolar);
                taskProcess1 = t_end;
            }

        break;
        case t_vCSubCoffeTask:
            {
                string msg = "执行V极化发射校准,减耦合系数、减通道系数";
                qlog_w("%s.",msg.c_str());
                startCali(uio_v_sendPolar);
                sendCalibSubC(uio_v_sendPolar);
                taskProcess1 = t_end;
            }

        break;
        /* 以下为接收部分 */
        case t_hRecvCycleTask:
            {
                string msg = "执行H极化接收手动校准,自动补接收手动系数";
                qlog_w("%s.",msg.c_str());
                startCali(uio_h_recvicePolar);
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
                calcOffsetValue2(uio_h_recvicePolar,taskFreq,false,AUTO_CALCULATE_RECV);
                msg = "可运行H极化接收手动补偿的计数: " + to_string(g_manualAmpCnt);
                qlog_w("%s.",msg.c_str());

            }
        break;
        case t_vRecvCycleTask:
            {
                string msg = "执行V极化接收手动校准,自动补接收手动系数";
                qlog_w("%s.",msg.c_str());

                startCali(uio_v_recvicePolar);
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
                calcOffsetValue2(uio_v_recvicePolar,taskFreq,false,AUTO_CALCULATE_RECV);
                msg = "可运行V极化接收手动补偿的计数: " + to_string(g_manualAmpCnt);
                qlog_w("%s.",msg.c_str());

            }
        break;


        case t_hRecvCali:
            {
                string msg = "执行H极化接收校准,不加系数";
                qlog_w("%s.",msg.c_str());
                sendCalibration(uio_h_recvicePolar,false);
                taskProcess1 = t_end;
            }
        break;

        case t_vRecvCali:
            {
                string msg = "执行V极化接收校准,不加系数";
                qlog_w("%s.",msg.c_str());
                sendCalibration(uio_v_recvicePolar,false);
                taskProcess1 = t_end;
            }
            
        break;

        case t_hRecvSubCoffTask:
            {
                string msg = "执行H极化接收校准,减耦合系数";
                qlog_w("%s.",msg.c_str());
                startCali(uio_h_recvicePolar);
                subCouplingCoffe(uio_h_recvicePolar);
                taskProcess1 = t_end;
            }

        break;

        case t_vRecvSubCoffTask:
            {
                string msg = "执行V极化接收校准,减耦合系数";
                qlog_w("%s.",msg.c_str());
                startCali(uio_v_recvicePolar);
                subCouplingCoffe(uio_v_recvicePolar);
                taskProcess1 = t_end;
            }

        break;
        
        case t_end:
            {
                taskProcess1 = t_wait;
                qlog_w("雷达校准,已完成!");
            }
        break;
        default:
            taskProcess1 = t_wait;
            qlog_n("雷达手动补平,复位!");
        break;
    }

}
/**
 * @description: 开启校准
 * @param {uioMode} st
 * @return {*}
 */
void crontab_uio::startCali(uioMode st)
{
    Server::Instance().m_sxk.m_uio->m_pub->request(st);//开启校准
}


/*** 
 * @description: 减耦合系数
 * @return {*}
 */
void crontab_uio::subCouplingCoffe(uioMode st)
{
    uint16_t g_usdata[65];
    struct cmdDataType cmdHeader;
    uint8_t m_freq = 0;
    cmdHeader.DeviceType = t_controlCmd;
    cmdHeader.source_DevType = CurDeviceType;
    cmdHeader.source_DevNum = ComponentNO;

    m_freq = Server::Instance().m_sxk.m_calibParam.m_calibFreq;//填入频率

    g_usdata[0] = Server::Instance().m_sxk.m_calibParam.m_calibFreq;//填入频率
    getCurrentCalibration(st,(unsigned char *)g_usSendData,sizeof(g_usSendData));
    subtractCouplingCoefficient(st,m_freq,g_usSendData);
    for(int i=0;i<CHANNEL_NUM;i++){
        g_usdata[i + 1] = g_usSendData[i];
        g_usdata[i + 1 + CHANNEL_NUM] = g_usSendData[i + CHANNEL_NUM];
    }

    setWebCmd(st,&cmdHeader);
    cmdHeader.dst_DevType =  leixing_SERVER_Sub_Unit_S;
    cmdHeader.dst_DevNum = 0;
    cmdHeader.dataLen = sizeof(g_usdata);
    Server::Instance().separate(s_web,1,&cmdHeader,(uint8_t *)g_usdata);
}


/*** 
 * @description: 减耦合系数、减通道系数
 * @param {uioMode} st
 * @return {*}
 */
void crontab_uio::sendCalibSubC(uioMode st)
{
    uint16_t g_usdata[65];
    struct cmdDataType cmdHeader;
    uint8_t m_freq = 0;
    cmdHeader.DeviceType = t_controlCmd;
    cmdHeader.source_DevType = CurDeviceType;
    cmdHeader.source_DevNum = ComponentNO;

    g_usdata[0] = Server::Instance().m_sxk.m_calibParam.m_calibFreq;//填入频率
    m_freq = Server::Instance().m_sxk.m_calibParam.m_calibFreq;//填入频率
    getCurrentCalibration(st,(unsigned char *)g_usSendData,sizeof(g_usSendData));
    subtractCouplingCoefficient(st,m_freq,g_usSendData);
    for(int i=0;i<CHANNEL_NUM;i++){
        g_usdata[i + 1] = g_usSendData[i]  - cCoefficientAmp[m_freq];
        g_usdata[i + 1 + CHANNEL_NUM] = g_usSendData[i + CHANNEL_NUM];
    }

    setWebCmd(st,&cmdHeader);
    cmdHeader.dst_DevType =  leixing_SERVER_Sub_Unit_S;
    cmdHeader.dst_DevNum = 0;
    cmdHeader.dataLen = sizeof(g_usdata);
    Server::Instance().separate(s_web,1,&cmdHeader,(uint8_t *)g_usdata);
}



/*** 
 * @description: 手动校准任务上报 不减耦合系数、不减通道系数,把时序卡和TR的对应频点的发射flash和发射缓存都清0
 * @param {uioMode} st
 * @param {bool} erase(是否使能擦除)
 * @return {*}
 */
void crontab_uio::sendCalibration(uioMode st,bool erase)
{
    struct cmdDataType cmdHeader;

    static uint16_t m_calibData[65];
    cmdHeader.DeviceType = t_controlCmd;
    cmdHeader.source_DevType = CurDeviceType;
    cmdHeader.source_DevNum = ComponentNO;
    
    if (erase) { 
        //清理缓存
        clearAPStatus(st,taskFreq);
        std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 等待清除
    }
    startCali(st);//触发校准
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 等待清除
    if(st == uio_h_sendPolar && wait(uio_h_sendPolar)){
        
        {//获取当前校准
            std::unique_lock<std::mutex> lk(g_CaliMutex);
            m_hSendCaliQueue->take((unsigned char *)m_calibData,sizeof(m_calibData));
            m_refreshSendH = false;//取消刷新
        }
    }
    if(st == uio_v_sendPolar && wait(uio_v_sendPolar)){

        {//获取当前校准
            std::unique_lock<std::mutex> lk(g_CaliMutex);
            m_vSendCaliQueue->take((unsigned char *)m_calibData,sizeof(m_calibData));
            m_refreshSendV = false;//取消刷新
        }
    }
    if(st == uio_h_recvicePolar && wait(uio_h_recvicePolar)){

        {//获取当前校准
            std::unique_lock<std::mutex> lk(g_CaliMutex);
            m_hRevCaliQueue->take((unsigned char *)m_calibData,sizeof(m_calibData));
            m_refreshRecvH = false;//取消刷新
        }
    }
    if(st == uio_v_recvicePolar && wait(uio_v_recvicePolar)){

        {//获取当前校准
            std::unique_lock<std::mutex> lk(g_CaliMutex);
            m_vRevCaliQueue->take((unsigned char *)m_calibData,sizeof(m_calibData));
            m_refreshRecvV = false;//取消刷新
        }
    }
    setWebCmd(st,&cmdHeader);
    cmdHeader.dst_DevType =  leixing_SERVER_Sub_Unit_S;
    cmdHeader.dst_DevNum = 0;
    cmdHeader.dataLen = sizeof(m_calibData);
    Server::Instance().separate(s_web,1,&cmdHeader,(uint8_t *)m_calibData);
}
/** 
 * @description: 读取本地耦合系数
 * @param {int} freq
 * @return {*}
 */
int crontab_uio::readCouplingParameters()
{
    std::string g_ucHFile,g_ucVFile;
    
    g_ucHFile = Conf::currentConf()->mFilePath.uFreqPointPath + std::string("/") + _H_COUPLE_VALUE_;
    g_ucVFile = Conf::currentConf()->mFilePath.uFreqPointPath + std::string("/") + _V_COUPLE_VALUE_;

    qlog_i("H极化发射耦合系数路径:%s",g_ucHFile.c_str());
    qlog_i("V极化发射耦合系数路径:%s",g_ucVFile.c_str());
    if(ReadFile(g_ucHFile.c_str(),(unsigned char *)hCoefficient,sizeof(hCoefficient)) < 0){
        qlog_e("没有发现发射H极化耦合文件路径 %s",g_ucHFile.c_str());
        return -1;
    }
    if(ReadFile(g_ucVFile.c_str(),(unsigned char *)vCoefficient,sizeof(vCoefficient)) < 0){
        qlog_e("没有发现发射V极化耦合文件路径 %s",g_ucVFile.c_str());
        return -1;
    }

    return 0;

}


/**
 * @description: 设置频点
 * @param {int} frequeue
 * @return {*}
 */
void crontab_uio::setFreq(int frequeue)
{
    // switch(frequeue)
    // {
    //     case t_changeFreq0:
    //         // setOperate(false);//停止时序发生器
    //         for(i=0;i<4;i++) {
    //             Server::Instance().m_sxk.CalibrationBeamMode(0,32+i);
    //         }
    //         std::this_thread::sleep_for(std::chrono::milliseconds(100));
    //     break;
    //     case t_changeFreq1:
    //         // setOperate(false);//停止时序发生器
    //         for(i=0;i<4;i++) {
    //             Server::Instance().m_sxk.CalibrationBeamMode(1,32+i);
    //         }

    //         std::this_thread::sleep_for(std::chrono::milliseconds(100));
    //     break;
    //     default:break;
    // }
}




/*** 
 * @description: 获取当前校准数据
 * @param {uioMode} st
 * @param {unsigned char} *dataOut
 * @param {int} len
 * @return {*}
 */
bool crontab_uio::getCurrentCalibration(uioMode st,unsigned char *dataOut,int len)
{
    // uint8_t m_freq[2];
    if (st == uio_h_sendPolar && wait(uio_h_sendPolar)) {
        //获取当前校准
        std::unique_lock<std::mutex> lk(g_CaliMutex);
        m_hSendCaliQueue->take();
        m_hSendCaliQueue->take();//2个字节的频率
        m_hSendCaliQueue->take((unsigned char *)dataOut,len);
        m_refreshSendH = false;//取消刷新
        
    } else if (st == uio_v_sendPolar && wait(uio_v_sendPolar)) {
        //获取当前校准
        std::unique_lock<std::mutex> lk(g_CaliMutex);
        m_vSendCaliQueue->take();
        m_vSendCaliQueue->take();//2个字节的频率
        m_vSendCaliQueue->take((unsigned char *)dataOut,len);
        m_refreshSendV = false;//取消刷新
    
    } else if(st == uio_h_recvicePolar && wait(uio_h_recvicePolar)) {
        //获取当前校准
        std::unique_lock<std::mutex> lk(g_CaliMutex);
        m_hRevCaliQueue->take();
        m_hRevCaliQueue->take();//2个字节的频率
        m_hRevCaliQueue->take((unsigned char *)dataOut,len);
        m_refreshRecvH = false;

    } else if (st == uio_v_recvicePolar && wait(uio_v_recvicePolar)) {
        //获取当前校准
        std::unique_lock<std::mutex> lk(g_CaliMutex);
        m_vRevCaliQueue->take();
        m_vRevCaliQueue->take();//2个字节的频率
        m_vRevCaliQueue->take((unsigned char *)dataOut,len);
        m_refreshRecvV = false;

    }
    else{
        qlog_e("获取当前校准数据模式错误.");
        return false;
    }
    return true;
}

/*** 
 * @description: 减去耦合系数
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {uint16_t*} calibrationData
 * @return {*}
 */
void crontab_uio::subtractCouplingCoefficient(uioMode st, unsigned int freq, uint16_t* calibrationData) 
{
    int g_temp = 0;
    if (st == uio_h_sendPolar) {
        for(int i=0;i<CHANNEL_NUM;i++){
            calibrationData[i] = (uint16_t)((calibrationData[i] - (hCoefficient[freq][i]*100)));
            g_temp = (calibrationData[i + CHANNEL_NUM]-(hCoefficient[freq][i + CHANNEL_NUM]*10)); //TODO:2024-12-12取模
            calibrationData[i+CHANNEL_NUM] = getModulo(g_temp,3600);
        }
    } else if (st == uio_v_sendPolar) {
        for(int i=0;i<CHANNEL_NUM;i++){
            calibrationData[i] = (uint16_t)((calibrationData[i] - (vCoefficient[freq][i]*100)));
            g_temp = (calibrationData[i + CHANNEL_NUM]-(vCoefficient[freq][i + CHANNEL_NUM]*10)); //TODO:2024-12-12取模
            calibrationData[i+CHANNEL_NUM] = getModulo(g_temp,3600);
        }
    } else if (st == uio_h_recvicePolar) {
        for(int i=0;i<CHANNEL_NUM;i++){
            calibrationData[i] = (uint16_t)((calibrationData[i] - (hCoefficient[freq][i]*100)));//2，3是自动耦合系数
            g_temp = (calibrationData[i + CHANNEL_NUM]-(hCoefficient[freq][i + CHANNEL_NUM]*10)); //取模
            calibrationData[i+CHANNEL_NUM] = getModulo(g_temp,3600);
        }
    } else if (st == uio_v_recvicePolar) {
        for(int i=0;i<CHANNEL_NUM;i++){
            calibrationData[i] = (uint16_t)((calibrationData[i] - (vCoefficient[freq][i]*100)));//2，3是自动耦合系数
            g_temp = (calibrationData[i + CHANNEL_NUM]-(vCoefficient[freq][i + CHANNEL_NUM]*10)); //取模
            calibrationData[i+CHANNEL_NUM] = getModulo(g_temp,3600);
        }
    }
}

/*** 
 * @description: 更新发射幅度偏移
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {uint16_t*} srcData
 * @param {uint16_t} *standAmpData
 * @return {*}
 */
void crontab_uio::updateAmplitudeOffset(uioMode st, unsigned int freq,const uint16_t* srcData,const uint16_t *standAmpData) 
{  
    int i=0,g_iTemp0=0;
    float g_fTemp0=0;
    int m_tmp[CHANNEL_NUM];

    {//计算偏移量
        
        memset(m_tmp,0,sizeof(m_tmp));
        memset((uint8_t *)&ddsSendStr,0,sizeof(ddsSendStr));
        ddsSendStr.freq = freq; //记录频点
        webCache.freq = freq;
        for (i=0; i < CHANNEL_NUM; i++) {
            webCache.ddsAmp[i] = srcData[i] - standAmpData[i];//记录下校准值的差值,用于上报雷象日志
            if(webCache.ddsAmp[i] > 50) { //通道值实际比标准值小，那么不需要计算修正衰减值

                g_fTemp0 = (float)(((webCache.ddsAmp[i])/0.5/2)/100);//换算比例0.5dbm，除2分级调节
                g_iTemp0 = ceil(g_fTemp0);
                ddsSendStr.ddsAmp[i] = g_iTemp0;
                // qlog_w("H极化通道%d,计算差值:%0.3f,int=%d.",i,g_fTemp0,g_iTemp0);

            } else if (webCache.ddsAmp[i] < 0) {
                // qlog_i("H极化,通道%d值实际比标准值小.",i);

                g_fTemp0 = (float)((abs(webCache.ddsAmp[i]))/100);//换算比例0.5dbm，除2分级调节
                m_tmp[i] = ceil(g_fTemp0);
                ddsSendStr.ddsAmp[i] = 0;
            } else {
                ddsSendStr.ddsAmp[i] = 0;
            }
        }
    }
    if (st == uio_h_sendPolar) { //保存一组缓存幅相值

        for(i=0; i<CHANNEL_NUM; i++) {

            ddsSendStr.ddsAmp[i] += ddsCacheStr_H.ddsAmp[i];

            if (ddsSendStr.ddsAmp[i] > m_tmp[i]) {
                ddsSendStr.ddsAmp[i] -= m_tmp[i];
            }
            if(ddsSendStr.ddsAmp[i] > 62) {
                ddsSendStr.ddsAmp[i] = 63;
            }
#if _LOG_UIO_
            qlog_n("H极化幅度补平通道%d,幅度标准值:%d,通道值:%d,耦合校准值:%d,幅度下发值:%d.",i,
            standAmpData[i],m_srcAp[i],srcData[i],ddsSendStr.ddsAmp[i]);
#endif

        }
        memcpy(ddsCacheStr_H.ddsAmp,ddsSendStr.ddsAmp,sizeof(ddsCacheStr_H.ddsAmp));
        send(uio_h_sendPolar,(unsigned char *)&ddsCacheStr_H,sizeof(ddsCacheStr_H));
    } else if(st == uio_v_sendPolar) {

        for(i=0; i<CHANNEL_NUM; i++) {

            ddsSendStr.ddsAmp[i] += ddsCacheStr_V.ddsAmp[i];

            if (ddsSendStr.ddsAmp[i] > m_tmp[i]) {
                ddsSendStr.ddsAmp[i] -= m_tmp[i];
            }
            if(ddsSendStr.ddsAmp[i] > 62) {
                ddsSendStr.ddsAmp[i] = 63;
            }
#if _LOG_UIO_
            qlog_n("V极化幅度补平通道%d,幅度标准值:%d,通道值:%d,耦合校准值:%d,幅度下发值:%d.",i,
            standAmpData[i],m_srcAp[i],srcData[i],ddsSendStr.ddsAmp[i]);
#endif            
        }
        memcpy(&ddsCacheStr_V.ddsAmp,ddsSendStr.ddsAmp,sizeof(ddsCacheStr_V.ddsAmp));
        send(uio_v_sendPolar,(unsigned char *)&ddsCacheStr_V,sizeof(ddsCacheStr_V));
    } else {
        qlog_e("幅度偏移值计算,校准模式错误.");
    }
    
}  

/*** 
 * @description: 更新发射相位偏移，添加最佳路径优化
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {uint16_t*} srcData
 * @param {uint16_t} *standPhaseData
 * @return {*}
 */
void crontab_uio::updatePhaseOffset(uioMode st, unsigned int freq,const uint16_t* srcData,const uint16_t *standPhaseData) 
{  
    int i=0,phaseDiff=0;
    short int m_phase[CHANNEL_NUM];
    {//计算偏移量
        memset(m_phase,0,sizeof(m_phase));

        webCache.freq = freq;
        for (i=0; i < CHANNEL_NUM; i++) {

            m_phase[i] = srcData[i+CHANNEL_NUM] - standPhaseData[i];
            // 将相位差规范化到[-1800, 1800]范围内(对应-180°到180°)
            if (m_phase[i] > 1800) {
                m_phase[i] -= 3600;
            } else if (m_phase[i] < -1800) {
                m_phase[i] += 3600;
            }

            webCache.ddsPhase[i] = m_phase[i];//记录下相位校准值的差值,用于上报雷象日志

            if(!is_within_tolerance(srcData[i+CHANNEL_NUM],standPhaseData[i])) { //不在50以内就处理
                m_phase[i] = m_phase[i] / getIntRandom(2,3);
            } else {
                m_phase[i] = 0;
            }
            
        }
    }
    if(st == uio_h_sendPolar) { //保存一组缓存幅相值
        int m = 0;
        for(i=0; i<CHANNEL_NUM; i++) {
            m = m_phase[i];

            m_phase[i] += ddsCacheStr_H.ddsPhase[i];
            ddsCacheStr_H.ddsPhase[i] = getModulo(m_phase[i],3600);
#if _LOG_UIO_
            qlog_n("H极化相位补平通道%d,相位标准值:%d,通道相位值:%d,耦合相位值:%d,修正值：%d,本次下发值:%d.",
                i,standPhaseData[i],m_srcAp[i+CHANNEL_NUM],srcData[i+CHANNEL_NUM],m,ddsCacheStr_H.ddsPhase[i]);
#endif

        }
        send(uio_h_sendPolar,(unsigned char *)&ddsCacheStr_H,sizeof(ddsCacheStr_H));
    } else if(st == uio_v_sendPolar) {

        int m = 0;
        for(i=0; i<CHANNEL_NUM; i++) {
            m = m_phase[i];

            m_phase[i] += ddsCacheStr_V.ddsPhase[i];
            ddsCacheStr_V.ddsPhase[i] = getModulo(m_phase[i],3600);
#if _LOG_UIO_
            qlog_n("V极化相位补平通道%d,相位标准值:%d,通道相位值:%d,耦合相位值:%d,修正值：%d,本次下发值:%d.",
                i,standPhaseData[i],m_srcAp[i+CHANNEL_NUM],srcData[i+CHANNEL_NUM],m,ddsCacheStr_V.ddsPhase[i]);
#endif

        }
        send(uio_v_sendPolar,(unsigned char *)&ddsCacheStr_V,sizeof(ddsCacheStr_V));
    } else {
        qlog_e("相位偏移值计算,校准模式错误.");
    }
    

}  


/*** 
 * @description: 更新接收校准通道偏移（数字域处理，不需要迭代）TODO：2025-8-19 只与标准值做比较
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {uint16_t*} srcData
 * @param {uint16_t} *standPhaseData
 * @return {*}
 */
void crontab_uio::updateRecvOffset(uioMode st, unsigned int freq,const uint16_t* srcData,const uint16_t *standData)
{
    int i = 0;
    int m_tmp = 0;
    int m_ampTmp[CHANNEL_NUM];
    memset(m_ampTmp,0,sizeof(m_ampTmp));
    memset(&ddsRecvStr,0,sizeof(ddsRecvStr));
    webCache.freq = freq;
    for (i=0; i < CHANNEL_NUM; i++) {
        //幅度计算
        m_tmp = srcData[i] - standData[i];
        webCache.ddsAmp[i] = m_tmp;//记录下校准值的差值,用于上报雷象日志
        if(m_tmp < 0) {
            ddsRecvStr.ddsAmp[i] = 0;
            m_ampTmp[i] = abs(m_tmp);//记录下校准值的差值，用于减下发的幅度值。实现可加可减
        } else {
            ddsRecvStr.ddsAmp[i] = m_tmp;
        }
        //相位计算
        m_tmp = srcData[i+CHANNEL_NUM] - standData[i+CHANNEL_NUM];
        webCache.ddsPhase[i] = m_tmp;//记录下校准值的差值,用于上报雷象日志 
        if(m_tmp < 0) {
            ddsRecvStr.ddsPhase[i] = 3600 - abs(m_tmp);
        } else {
            ddsRecvStr.ddsPhase[i] = getModulo(m_tmp,3600);
        }
    }
    
    if ( st == uio_h_recvicePolar) {

        memcpy(&ddsCacheRecv_H,&ddsRecvStr,sizeof(ddsCacheStr_H));

#if _LOG_UIO_
        for(i=0; i<CHANNEL_NUM; i++) {

            qlog_n("H接收补平通道%d,幅度标准值:%d,相位标准值:%d,幅度:%d,相位:%d,修正值：%d,%d.",
                i,
                standData[i],standData[i+CHANNEL_NUM],
                srcData[i],srcData[i+CHANNEL_NUM],
                ddsRecvStr.ddsAmp[i],ddsRecvStr.ddsPhase[i]);
        }
#endif


    } 
    
    if ( st == uio_v_recvicePolar ) {

        memcpy(&ddsCacheRecv_V,&ddsRecvStr,sizeof(ddsCacheStr_H));

#if _LOG_UIO_
        for(i=0; i<CHANNEL_NUM; i++) {
            qlog_n("V接收补平通道%d,幅度标准值:%d,相位标准值:%d,幅度:%d,相位:%d,修正值：%d,%d.",
                i,
                standData[i],standData[i+CHANNEL_NUM],
                srcData[i],srcData[i+CHANNEL_NUM],
                ddsRecvStr.ddsAmp[i],ddsRecvStr.ddsPhase[i]);

        }
#endif

    }


}


/*** 
 * @description: 执行接收数字域补偿下发
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {int} mode
 * @param {ap_Control_t&} apCtrl
 * @return {*}
 */
void crontab_uio::recvCompensation(uioMode st, unsigned int freq, int mode, struct ap_Control_t& apCtrl)
{
    static uint16_t caliCoff[32][2];
    static short int m_Real[32],m_Image[32];
    for(int i=0; i<32; i++) {
        caliCoff[i][0] = apCtrl.ddsAmp[i];
        caliCoff[i][1] = apCtrl.ddsPhase[i];
    }
    struct plAlignCoeff m_coe;
    short tmp = 0;
    for(int i=0 ;i < 32; i++) { //j代表通道
        m_coe.Coe_Image = 0;
        m_coe.Coe_Real = 0;
        sysCalibCalculate(caliCoff[i][0],caliCoff[i][1],m_coe);
        // 交换实部和虚部
        tmp = m_coe.Coe_Image;
        m_coe.Coe_Image = m_coe.Coe_Real;
        m_coe.Coe_Real = tmp;
        
        m_Real[i] = m_coe.Coe_Real;
        m_Image[i] = m_coe.Coe_Image;
    }

    if(freq == 0) {
        if(mode == AUTO_CALCULATE) {
            if(st == uio_h_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_h_q0Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_h_i0Buffer = m_Image[i];
                }
            }
            if(st == uio_v_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_v_q0Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_v_i0Buffer = m_Image[i];
                }
            }
            
        }
        if(mode == MANUAL_CALCULATE) {
            if(st == uio_h_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_h_q0Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_h_i0Buffer = m_Image[i];
                }
            }
            if(st == uio_v_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_v_q0Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_v_i0Buffer = m_Image[i];
                }
            }
        }
        
    } else {
        if(mode == AUTO_CALCULATE) {
            if(st == uio_h_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_h_q1Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_h_i1Buffer = m_Image[i];
                }
            }
            if(st == uio_v_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_v_q1Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxAutoCaliCoe[i].m_v_i1Buffer = m_Image[i];
                }
            }
            
        }
        if(mode == MANUAL_CALCULATE) {
            if(st == uio_h_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_h_q1Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_h_i1Buffer = m_Image[i];
                }
            }
            if(st == uio_v_recvicePolar) {
                for(int i=0; i<CHANNEL_NUM; i++) {
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_v_q1Buffer = m_Real[i];
                    Server::Instance().m_sxk.m_rxManualCaliCoe[i].m_v_i1Buffer = m_Image[i];
                }
            }
        }
        
    }
    if(mode == AUTO_CALCULATE) {
        Server::Instance().m_event.triggerEvent(WRITE_AUTOCALI_COE);//启动写入自动校准系数
    } else {
        Server::Instance().m_event.triggerEvent(WRITE_MANUALCALI_COE);//启动写入手动校准系数
    }
}


/*** 
 * @description: 计算当前幅度补偿值第二版
 * 幅度修正值计算：将获取出来的IQ换算成幅相值后减去通道耦合系数，再减去下发的多评点幅度基准值。最后得到的值除以0.5dbm取整。
 * 相位修正值计算：将获取出来的IQ换算成相位值后将去通道耦合系数，判断是否大于360，如果是则用360减去这个相位值后再减去相位基准值，最后除以5.625取整。
 *                                                                           如果小于360，则将相位值减去相位基准值，最后除以5.625取整。
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {bool} update
 * @param {int} apMode(选幅度还是相位补偿)
 * @return {*}
 */
uioMode crontab_uio::calcOffsetValue2(uioMode st,unsigned int freq, bool update,int apMode)
{
    static uint16_t m_dataTmp[CHANNEL_NUM*2];
    //1、获取校准值，需要先触发PL校准
    auto ret = getCurrentCalibration(st,(unsigned char *)g_usSendData,sizeof(g_usSendData));
    if(ret == false) {
        qlog_e("获取校准值失败.");
        return uio_noReply;
    }
    memcpy(m_srcAp,g_usSendData,sizeof(m_srcAp));//保存源数据
    //2、将数据减耦合系数
    subtractCouplingCoefficient(st,freq,g_usSendData);

    if(apMode == AUTO_CALCULATE_AMP) {
        //3、计算并下发幅度偏移值
        if (st == uio_h_sendPolar) {
            memcpy(m_dataTmp,mulitFreqStr.hSendAmp[freq],sizeof(mulitFreqStr.hSendAmp[freq]));
        } else if(st == uio_v_sendPolar) {
            memcpy(m_dataTmp,mulitFreqStr.vSendAmp[freq],sizeof(mulitFreqStr.vSendAmp[freq]));
        } 
        updateAmplitudeOffset(st,freq,g_usSendData,m_dataTmp);
    } 
    if(apMode == AUTO_CALCULATE_PHASE)
    {
        //3、计算并下发相位偏移值
        if (st == uio_h_sendPolar) {
            memcpy(m_dataTmp,mulitFreqStr.hSendPhase[freq],sizeof(mulitFreqStr.hSendPhase[freq]));
        } else if(st == uio_v_sendPolar) {
            memcpy(m_dataTmp,mulitFreqStr.vSendPhase[freq],sizeof(mulitFreqStr.vSendPhase[freq]));
        }
        updatePhaseOffset(st,freq,g_usSendData,m_dataTmp);
    } 
    if(apMode == AUTO_CALCULATE_AMP_PHASE) 
    {
        //4、计算并下发幅相偏移值
        if (st == uio_h_sendPolar) {
            memcpy(m_dataTmp,mulitFreqStr.hSendAmp[freq],sizeof(mulitFreqStr.hSendAmp[freq]));
            memcpy(&m_dataTmp[32],mulitFreqStr.hSendPhase[freq],sizeof(mulitFreqStr.hSendPhase[freq]));
        } else if(st == uio_v_sendPolar) {
            memcpy(m_dataTmp,mulitFreqStr.vSendAmp[freq],sizeof(mulitFreqStr.vSendAmp[freq]));
            memcpy(&m_dataTmp[32],mulitFreqStr.vSendPhase[freq],sizeof(mulitFreqStr.vSendPhase[freq]));
        } 
        //先幅度再相位
        updateAmplitudeOffset(st,freq,g_usSendData,m_dataTmp);

        updatePhaseOffset(st,freq,g_usSendData,&m_dataTmp[32]);
    }
    if(apMode == AUTO_CALCULATE_RECV) {
        //5、计算并下发接收偏移值
        if(st == uio_h_recvicePolar){
            for(int i=0; i<CHANNEL_NUM; i++) {
                m_dataTmp[i] = recvMulitFreqStr.hRecvAmp[freq][i];
                m_dataTmp[CHANNEL_NUM + i] = recvMulitFreqStr.hRecvPhase[freq][i];
            }
        } else if ( st == uio_v_recvicePolar) {
            for(int i=0; i<CHANNEL_NUM; i++) {
                m_dataTmp[i] = recvMulitFreqStr.vRecvAmp[freq][i];
                m_dataTmp[CHANNEL_NUM + i] = recvMulitFreqStr.vRecvPhase[freq][i];
            }
        }
        updateRecvOffset(st,freq,m_srcAp,m_dataTmp); //改成原始值计算
        
    }   
    if(update) {
        //5、上报雷象差值
        send(st);
        memset(&webCache,0,sizeof(webCache));
    }
    return st;

}

/*** 
 * @description: 清除幅度相位值
 * @param {uioMode} st
 * @param {int} freq(指定频点)
 * @return {*}
 */
void crontab_uio::clearAPStatus(uioMode st,int freq)
{
    qlog_w("减通道系数,时序卡自动校准幅相缓存清0,TR对应极化频点清0");
    memset((uint8_t *)&ddsSendStr,0,sizeof(ddsSendStr));
    ddsSendStr.freq = freq;
    send(st,(unsigned char *)&ddsSendStr,sizeof(ddsSendStr));
    std::this_thread::sleep_for(std::chrono::milliseconds(20));

    (st == uio_h_sendPolar)?
    memset(&ddsCacheStr_H,0,sizeof(ddsCacheStr_H)):
    memset(&ddsCacheStr_V,0,sizeof(ddsCacheStr_V));
}

/**
 * @description: 处理雷达状态
 * @return {*}
 */
bool crontab_uio::startOperate()
{
    g_ifreq = readIntValue("paramsConfig","freqPoint",Server::Instance().m_configPath.c_str());//并记录当前校准参数频点
    return (Server::Instance().m_sxk.m_controlReg.m_timingStatus == 0x01);//如果雷达正在运行，那么可以开始校准
}

/*** 
 * @description: 设置雷达运行状态
 * @return {*}
 */
void crontab_uio::setOperate(bool ret)
{
    if(ret) {
        Server::Instance().m_sxk.m_controlReg.m_timingStatus = 0x01;
    } else {
        Server::Instance().m_sxk.m_controlReg.m_timingStatus = 0x06;
    }
    Server::Instance().m_event.triggerEvent(WRITE_CONTROL_REG);//启动写入控制寄存器
    std::this_thread::sleep_for(std::chrono::milliseconds(20));
}


/**
 * @description: 定时任务
 * @param {SXK_Unit} *argc
 * @return {*}
 */
void crontab_uio::crontab_Thread_Func(crontab_uio *argc)
{    
    pthread_setname_np(pthread_self(),"crontabFunc");
    while(argc->m_RunFlag)
    {    
        if (sysRunStatus != SYS_RUN) {
            qlog_d("自动校准线程暂停运行...");
            std::this_thread::sleep_for(std::chrono::milliseconds(600));
            continue;
        }
        argc->task();
        argc->autoPoll();
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

}